home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
telecomm
/
sticpsrc.lzh
/
SOURCE.ARC
/
CMDPARSE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-09-23
|
6KB
|
218 lines
/* Parse command line, set up command arguments Unix-style, and call function.
* Note: argument is modified (delimiters are overwritten with nulls)
* Improved error handling by Brian Boesch of Stanford University
*/
#include <stdio.h>
#include <ctype.h>
#include "global.h"
#include "cmdparse.h"
int
cmdparse(cmds,line)
struct cmds cmds[];
register char *line;
{
register char *pp,*rp,*ep,*vp;
char *cp,*argv[NARG],*getenv();
static char pool[POOLSIZE];
int argc,quote;
char c;
/* Remove cr/lf */
rip(line);
for(argc = 0;argc < NARG;argc++)
argv[argc] = NULLCHAR;
pp = pool;
for(argc = 0;argc < NARG && *line != '\0';){
quote = 0;
/* Skip leading white space */
while(*line == ' ' || *line == '\t')
line++;
if(*line == '\0')
break;
/* Check for quoted token */
if(*line == '"' || *line == '\'')
quote = *line++; /* Suppress quote, remember it */
argv[argc++] = line; /* Beginning of token */
/* Find terminating delimiter */
if(quote){
/* Find quote, it must be present */
if((line = index(line,quote)) == NULLCHAR)
return -1;
*line++ = '\0';
} else {
/* Find space or tab. If not present,
* then we've already found the last
* token.
*/
for (cp = line; *cp; cp++)
if (*cp == ' ' || *cp == '\t')
break;
if (*cp != '\0')
*cp++ = '\0';
line = cp;
}
/* Check for variablename */
if(quote != '\'' && index(cp = argv[argc - 1],'$') != NULLCHAR){
argv[argc - 1] = pp;
while (*cp != '\0') {
if (*cp != '$')
*pp++ = *cp++;
else {
if (*++cp == '{') {
if ((ep = index(++cp,'}')) == NULLCHAR)
return -1;
*ep++ = '\0';
} else {
ep = NULLCHAR;
}
/* Scan to end of varname and mark it */
for (vp = cp; isalnum(*vp) || *vp == '_'; vp++)
*vp = toupper(*vp);
/* If a name found, get value */
if (vp != cp){
c = *vp; /* save next and make \0 */
*vp = '\0';
rp = getenv(cp);
*vp = c; /* restore next character */
if (ep == NULLCHAR){ /* no braces */
if (rp == NULLCHAR) /* undef'd var */
rp = ""; /* then just empty */
} else {
if (rp == NULLCHAR) /* undef'd var */
switch (c) { /* else look at next */
case '=':
dosetenv(2,(&cp)-1);/* assign and subst */
case '-':
rp = vp + 1; /* subst next word */
break;
case '?':
if (*++vp == '\0')
vp = "undefined variable";
printf("%s\n",vp);
return -1;
default:
rp = ""; /* default is empty */
}
else
if (c == '+') /* defined and subst */
rp = vp + 1;
}
/* Copy the result to the pool */
while ((*pp++ = *rp++) != '\0')
;
pp--;
cp = vp;
}
if (ep != NULLCHAR)
cp = ep;
}
}
*pp++ = '\0';
if (pp > pool + POOLSIZE){ /* check pool overflow */
printf("PANIC: pool overflow\n");
fflush(stdout);
for (;;) /* dangerous to continue */
;
}
}
}
if (argc < 1) { /* empty command line */
argc = 1;
argv[0] = "";
}
/* Lines beginning with "#" are comments */
if(argv[0][0] == '#')
return 0;
return docmd(cmds,argc,argv); /* execute command */
}
/* Call a command based on the first token in an already-parsed line */
int
docmd(tab,argc,argv)
struct cmds tab[];
int argc;
char *argv[];
{
register struct cmds *cmdp;
int rslt;
/* Look up command in table; prefix matches are OK */
for(cmdp = tab;cmdp->name != NULLCHAR;cmdp++){
if(strncmp(argv[0],cmdp->name,strlen(argv[0])) == 0)
break;
}
if(cmdp->name == NULLCHAR) {
if(cmdp->argc_errmsg != NULLCHAR)
printf("%s\n",cmdp->argc_errmsg);
return -1;
}
if(argc < cmdp->argcmin) {
/* Insufficient arguments */
printf("Usage: %s %s\n",cmdp->name,cmdp->argc_errmsg);
return -1;
}
argv[0] = cmdp->name;
rslt = (*cmdp->func)(argc,argv);
if ((rslt < 0) && (cmdp->exec_errmsg != NULLCHAR))
printf("%s\n",cmdp->exec_errmsg);
return(rslt);
}
/* Call a subcommand based on the first token in an already-parsed line */
int
subcmd(tab,argc,argv)
struct cmds tab[];
int argc;
char *argv[];
{
int rslt,len;
register struct cmds *cmdp;
/* Strip off first token and pass rest of line to subcommand */
if (argc < 2) {
if (argc < 1)
printf("SUBCMD - Don't know what to do?\n");
else
printf("\"%s\" - takes at least one argument\n",argv[0]);
return -1;
}
for(cmdp = tab;cmdp->name != NULLCHAR;cmdp++){
if(strncmp(argv[1],cmdp->name,strlen(argv[1])) == 0){
if(--argc < cmdp->argcmin) {
if (cmdp->argc_errmsg != NULLCHAR)
printf("Usage: %s %s %s\n",
argv[0],cmdp->name,cmdp->argc_errmsg);
return -1;
}
(++argv)[0] = cmdp->name;
rslt = (*cmdp->func)(argc,argv);
if ((rslt < 0) && (cmdp->exec_errmsg != NULLCHAR))
printf("%s\n",cmdp->exec_errmsg);
return(rslt);
}
}
if (cmdp->argc_errmsg != NULLCHAR){
if (cmdp->argc_errmsg[0] != '?'){
printf("%s\n",cmdp->argc_errmsg);
} else {
printf("%s %s:",argv[0],cmdp->argc_errmsg + 1);
len = strlen(argv[0]) + strlen(cmdp->argc_errmsg) + 1;
for(cmdp = tab;cmdp->name != NULLCHAR;cmdp++){
if ((len += strlen(cmdp->name) + 1) > 79){
len = strlen(cmdp->name) + 9;
printf("\n ");
}
printf(" %s",cmdp->name);
}
printf("\n");
}
}
return -1;
}